package main

/*
#cgo LDFLAGS: -L. -lsoraka -lstdc++
#include <stdlib.h> // 必须包含此头文件才能使用free
#include "crpc.h"

// 声明Go实现的回调函数（实际实现在Go中）
unsigned int srpc_message_proc_go(int msgType, char* service, char* routine,
                                char* payload, char* sender, char* target,
                                char* peerIP, void* retdata, void* userptr);
void srpc_connready_cb_go(char* jsonstr, void* userptr);
void srpc_connreset_cb_go(unsigned int retcode, void* userptr);
*/
import "C"
import (
	"fmt"
	"unsafe"
)

var flag bool

//export srpc_message_proc_go
func srpc_message_proc_go(msgType C.int, service *C.char, routine *C.char,
	payload *C.char, sender *C.char, target *C.char,
	peerIP *C.char, retdata unsafe.Pointer, userptr unsafe.Pointer) C.uint {
	println("[消息处理] 类型=", int(msgType), "服务=", C.GoString(service), "方法=", C.GoString(routine))
	if msgType == 2 {
		resp := C.CString("{\"status\":\"success\"}")
		defer C.free(unsafe.Pointer(resp))
		//C.srpc_databuf_assign((C.SRPC_DATABUF)(retdata), resp, C.uint(len("{\"status\":\"success\"}")))
		// 修正：将resp直接作为char*传递，不需要转换
		//C.srpc_databuf_assign((C.SRPC_DATABUF)(retdata), unsafe.Pointer(resp), C.uint(C.strlen(resp)))
		// 使用Go的len函数获取字符串长度
		C.srpc_databuf_assign((C.SRPC_DATABUF)(retdata), unsafe.Pointer(resp), C.uint(len("{\"status\":\"success\"}")))
	}
	return C.SRPC_SOK
}

//export srpc_connready_cb_go
func srpc_connready_cb_go(jsonstr *C.char, userptr unsafe.Pointer) {
	println("[连接状态] 已连接:", C.GoString(jsonstr))
	flag = true
}

//export srpc_connreset_cb_go
func srpc_connreset_cb_go(retcode C.uint, userptr unsafe.Pointer) {
	println("[连接状态] 断开连接，错误码:", uint(retcode))
	flag = false
}

func initSRPC() {
	// 1. 创建消息处理器
	dealer := C.srpc_dealer_create(
		C.srpc_message_proc(C.srpc_message_proc_go),
		C.srpc_connready_cb(C.srpc_connready_cb_go),
		C.srpc_connreset_cb(C.srpc_connreset_cb_go),
		nil,
	)
	if dealer == nil {
		panic("Failed to create dealer")
	}
	fmt.Println("Dealer created")

	// 2. 添加服务
	serviceName := C.CString("SECServer")
	defer C.free(unsafe.Pointer(serviceName))
	addResult := C.srpc_add_service(dealer, serviceName, C.CString("TestService"), nil, nil)
	if C.srpc_result_failed(addResult) != 0 {
		fmt.Printf("Failed to add service, code: %d\n", addResult)
		return
	}
	fmt.Println("Service added")

	// 3. 启动消息处理器
	addr := C.CString("192.40.32.100") // 消息网关地址
	port := C.int(10080)               // 消息网关端口
	defer C.free(unsafe.Pointer(addr)) // 释放地址内存
	startResult := C.srpc_dealer_start(dealer, addr, port)
	if C.srpc_result_failed(startResult) != 0 {
		fmt.Printf("Start failed: %d\n", startResult)
		return
	}
	fmt.Println("Service started")
}

func main() {
	go func() {
		initSRPC()
		for !flag {
			// 空循环等待回调，实际项目中建议加time.Sleep
		}
		println("成功接收到回调！")
	}()

	// 主线程阻塞
	select {}
}
